package cn.zs.supply.common.core.web.config;

import brave.Tracer;
import cn.zs.supply.common.constants.PubKeyDef;
import cn.zs.supply.common.constants.enums.MsgDataEnum;
import cn.zs.supply.common.core.context.RibbonFilterContextHolder;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.codec.Decoder;
import feign.codec.Encoder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
public class BaseFeignConfig {
    @Autowired
    Tracer tracer;
    @Value("${spring.application.name}")
    private String applicationName;
    @Value("${global.workerId}")
    private long workerId = 1;
    private HttpMessageConverters httpMessageConverters = createConverters();


    @Bean
    public Decoder feignDecoder() {
        ObjectFactory<HttpMessageConverters> objectFactory = () -> this.httpMessageConverters;
        return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
    }

    @Bean
    public Encoder feignEncoder() {
        ObjectFactory<HttpMessageConverters> objectFactory = () -> this.httpMessageConverters;
        Encoder encoder = new SpringEncoder(objectFactory);
        return encoder;
    }

    public HttpMessageConverters createConverters() {
        MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(customObjectMapper());
        jacksonConverter.setDefaultCharset(Charset.forName("UTF-8"));
        StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
        stringConverter.setDefaultCharset(Charset.forName("UTF-8"));
        return new HttpMessageConverters(jacksonConverter, stringConverter);
    }

    public ObjectMapper customObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        /**
         * 序列换成json时,将所有的long变成string
         * 因为js中得数字类型不能包含所有的java long值
         */
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        objectMapper.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        return objectMapper;
    }


    /**
     * 创建Feign请求拦截器，在发送请求前设置认证的token,各个微服务将token设置到环境变量中来达到通用
     *
     * @return
     */
    @Bean
    public FeignHeaderRequestInterceptor feignRequestInterceptor() {
        return new FeignHeaderRequestInterceptor();
    }

    public class FeignHeaderRequestInterceptor implements RequestInterceptor {
        public FeignHeaderRequestInterceptor() {
        }
        @Override
        public void apply(RequestTemplate template) {
            //设置reqSource为当前应用程序
            String serviceName = applicationName + ":" + workerId;
            template.header(PubKeyDef.HEADER_REQ_SOURCE, serviceName.substring(serviceName.lastIndexOf("-") + 1));
            String token=System.getProperty(MsgDataEnum.FEIGN_TOKEN.getCode());
            if(!StringUtils.isBlank(token)) {
                template.header("Authentication", token);
            }
        }
    }




}

